package com.lzk.auth.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lzk.auth.service.DeviceService;
import com.lzk.auth.service.FactoryService;
import com.lzk.auth.service.OrderService;
import com.lzk.auth.service.PlanService;
import com.lzk.common.result.Result;

import com.lzk.model.system.SysFactory;
import com.lzk.model.system.SysOrder;
import com.lzk.model.system.SysPlan;
import com.lzk.vo.StatisticsVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;

@Api(tags = "数据统计")
@RestController
@RequestMapping("/admin/statistics")
public class AnalyseDataController {
    @Autowired
    private PlanService planService;

    @Autowired
    private DeviceService deviceService;
    @Autowired
    private OrderService orderService;

    @Autowired
    private FactoryService factoryService;

    @GetMapping("device")
    public Result getDeviceStatus() {
        List<Integer> deviceStatus = deviceService.deviceStatus();

        return Result.ok(deviceStatus);
    }
    @GetMapping("order/{time}")
    public Result getOrderStatus(@PathVariable Integer time) {
        LocalDateTime startTime;
        LocalDateTime endTime;
        switch (time) {
            case 1:
                startTime = LocalDateTime.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).with(LocalTime.MIN);
                endTime = LocalDateTime.now().with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)).with(LocalTime.MAX);
                break;
            case 2:
                startTime = LocalDateTime.now().with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
                endTime = LocalDateTime.now().with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
                break;
            case 3:
                startTime = LocalDateTime.now().with(TemporalAdjusters.firstDayOfYear()).with(LocalTime.MIN);
                endTime = LocalDateTime.now().with(TemporalAdjusters.lastDayOfYear()).with(LocalTime.MAX);
                break;
            default:
                return null;
        }

        LambdaQueryWrapper<SysPlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(SysPlan::getStartTime, startTime);
        wrapper.lt(SysPlan::getStartTime, endTime);
        List<SysPlan> list = planService.list(wrapper);

        int[] order = new int[3];
        for (SysPlan sysPlan : list) {
            LocalTime bookingStartTime = sysPlan.getStartTime().toLocalTime();
            if (bookingStartTime.isAfter(LocalTime.of(8, 0)) && bookingStartTime.isBefore(LocalTime.of(12, 0))) {
                order[0]++;
            } else if (bookingStartTime.isAfter(LocalTime.of(12, 0)) && bookingStartTime.isBefore(LocalTime.of(18, 0))) {
                order[1]++;
            } else if (bookingStartTime.isAfter(LocalTime.of(18, 0)) && bookingStartTime.isBefore(LocalTime.of(22, 0))) {
                order[2]++;
            }
        }
        return Result.ok(order);
    }

    @GetMapping("plan")
    public Result getSalary() {
        List<Integer> salary = planService.salary();
        return Result.ok(salary);
    }

    @ApiOperation(value = "查看本日收益")
    @GetMapping("getSalaryByDay")
    public Result getSalaryByDay() {
        LocalDateTime startOfToday = LocalDateTime.now().toLocalDate().atStartOfDay().withHour(8);
        LocalDateTime endOfToday = LocalDateTime.now();
        List<StatisticsVo> salaryList = new ArrayList<>();

        LocalDateTime currentHour = startOfToday;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("H时");
        while (currentHour.isBefore(endOfToday) || currentHour.isEqual(endOfToday)) {
            LocalDateTime nextHour = currentHour.plusHours(1);
            LambdaQueryWrapper<SysPlan> wrapper = new LambdaQueryWrapper<>();
            wrapper.ge(SysPlan::getStartTime, currentHour);
            wrapper.lt(SysPlan::getStartTime, nextHour);
            List<SysPlan> list = planService.list(wrapper);

            int salary = getTotalCount(list);
            String hour = currentHour.format(formatter);
            StatisticsVo statisticsVo = new StatisticsVo(hour, salary);
            statisticsVo.setSysPlanList(list);
            salaryList.add(statisticsVo);
            currentHour = nextHour;
        }
        return Result.ok(salaryList);
    }

    @ApiOperation(value = "查看近6个月收益")
    @GetMapping("getSalaryByMonth")
    public Result getSalaryByMonth() {

        LocalDateTime endOfSixMonths = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).withNano(999999999);
        LocalDateTime startOfSixMonths = endOfSixMonths.minusMonths(5).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);

        List<StatisticsVo> salaryList = new ArrayList<>();

        LocalDate currentMonth = startOfSixMonths.toLocalDate();
        while (currentMonth.isBefore(endOfSixMonths.toLocalDate()) || currentMonth.isEqual(endOfSixMonths.toLocalDate())) {
            LocalDate nextMonth = currentMonth.plusMonths(1);
            LocalDateTime nextMonthStart = LocalDateTime.of(nextMonth, LocalTime.MIN);
            LambdaQueryWrapper<SysPlan> wrapper = new LambdaQueryWrapper<>();
            wrapper.ge(SysPlan::getStartTime, currentMonth);
            wrapper.lt(SysPlan::getStartTime, nextMonthStart);
            List<SysPlan> list = planService.list(wrapper);

            int salary =getTotalCount(list);
            StatisticsVo statisticsVo = new StatisticsVo(currentMonth, salary);
            statisticsVo.setSysPlanList(list);
            salaryList.add(statisticsVo);
            currentMonth = nextMonth;
        }
        return Result.ok(salaryList);
    }

    @ApiOperation(value = "查看近六日收益")
    @GetMapping("getSalaryByWeek")
    public Result getSalaryByWeek() {

        LocalDateTime endOfWeek = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).withNano(999999999);
        LocalDateTime startOfWeek = endOfWeek.minusDays(6).withHour(0).withMinute(0).withSecond(0).withNano(0);

        List<StatisticsVo> salaryList = new ArrayList<>();
        LocalDateTime currentDay = startOfWeek;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M月d日");
        while (currentDay.isBefore(endOfWeek) || currentDay.isEqual(endOfWeek)) {
            LocalDateTime nextDay = currentDay.plusDays(1);
            LambdaQueryWrapper<SysPlan> wrapper = new LambdaQueryWrapper<>();
            wrapper.ge(SysPlan::getStartTime, currentDay);
            wrapper.lt(SysPlan::getStartTime, nextDay);
            List<SysPlan> list = planService.list(wrapper);
            int salary = getTotalCount(list);
            String day = currentDay.format(formatter);
            StatisticsVo statisticsVo = new StatisticsVo(day, salary);
            statisticsVo.setSysPlanList(list);
            salaryList.add(statisticsVo);
            currentDay = nextDay;
        }

        return Result.ok(salaryList);

    }

    private Integer getTotalCount(List<SysPlan> sysPlans) {
        int total=0;
        for (SysPlan sysPlan : sysPlans) {
            LocalDateTime endTime = sysPlan.getEndTime();
            int month = endTime.getMonthValue();
            int year = endTime.getYear();
            if (month >= 1 && month <= 12 && year==2023) {
                Long orderId = sysPlan.getOrderId();
                SysOrder sysOrder = orderService.getById(orderId);
                if (sysOrder != null) {
                    String pCount = sysOrder.getPCount();
                    String[] counts = pCount.split(",");

                    for (String count : counts) {
                        Integer countNumber=Integer.parseInt(String.valueOf(count));
                        total+=countNumber;

                    }


                }
            }
        }
        return total;
    }


    @GetMapping("deviceCount")
    public Result deviceCount() {
        List<SysFactory> list = factoryService.list();
        return Result.ok(list);
    }
}
